package designpatterns.behavior;

import java.util.ArrayList;
import java.util.List;

/**
 * 观察者模式：定义对象间的一种一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并被自动更新。
 * 优点：1、观察者和被观察者是抽象耦合（降低了目标与观察者之间的耦合关系）的。
 *      2、建立一套触发机制。
 * 缺点：1、目标与观察者之间的依赖关系并没有完全解除，而且有可能出现循环引用。
 *      2、当观察者对象很多时，通知的发布会花费很多时间，影响程序的效率。
 * 使用场景：一个对象的改变将导致其他一个或多个对象也发生改变，而不知道具体有多少对象将发生改变，可以降低对象之间的耦合度。
 *          一个对象必须通知其他对象，而并不知道这些对象是谁。
 * @author jack.wu
 * @since 2019/12/4 17:23
 */
public abstract class Observer {

    protected Subject subject;

   public abstract void update();
}

class Subject {
    /**
     * 观察者
     */
    private List<Observer> observers = new ArrayList<>(10);

    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public void attach(Observer observer){
        observers.add(observer);
    }

    public void notifyAllObserver(){
        for (Observer observer : observers){
            observer.update();
        }
    }
}

class BinaryObserver extends Observer{

    public BinaryObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("Binary String:" + Integer.toBinaryString(subject.getState()));
    }
}

class OctalObserver  extends Observer{

    public OctalObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("Octal String:" + Integer.toOctalString(subject.getState()));
    }
}

class HexObserver extends Observer{

    public HexObserver (Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("Hex String:" + Integer.toHexString(subject.getState()));
    }
}
